<?php

namespace App\Admin\Utils;

use App\Admin\Form;
use App\Admin\Form\Field;
use App\Admin\Traits\CanValidate;
use App\Models\Config as ConfigModel;
use Illuminate\Http\Request;

class Config
{
    use CanValidate;

    /**
     * @var Request
     */
    private $request;

    /**
     * @var Form
     */
    private $form;

    private static $configPrefix = 'admin';

    public function __construct()
    {
        $this->initFields();
    }

    public static function load()
    {
        try {
            $configs = ConfigModel::pluck('value', 'name')->toArray();
        } catch (\Exception $e) {
            $configs = [];
        }

        foreach ($configs as $key => $config) {
            config([static::$configPrefix.'.'.$key => $config]);
        }
    }

    private function initFields()
    {
        $this->form = new Form(ConfigModel::class, function (Form $form) {
            $form->text('app_name', '系统名')
                 ->value(config('admin.app_name'));

            $form->text('wechat_oauth_domain', '公众号授权域名')
                 ->value(config('admin.wechat_oauth_domain'));

            $form->text('official_account_app_id', '公众号 APP ID')
                 ->value(config('admin.official_account_app_id'));

            $form->text('official_account_secret', '公众号 SECRET')
                 ->value(config('admin.official_account_secret'));

            $form->text('official_account_token', '公众号 TOKEN')
                 ->value(config('admin.official_account_token'));

            $form->text('official_account_aes_key', '公众号 AES KEY')
                 ->value(config('admin.official_account_aes_key'));
        });
    }

    public function renderForm()
    {
        return view('admin.config', ['fields' => $this->form->builder()->fields()])->render();
    }

    public function store(Request $request)
    {
        $this->request = $request;

        $this->validate();

        $updatedSuccess = $this->updateConfigs($this->getNeededUpdateConfigs());

        return $updatedSuccess;
    }

    private function validate()
    {
        $validator = \Validator::make(
            $this->request->all(),
            $this->validateRules(),
            $this->validateMessages(),
            $this->validateAttributes()
        );

        if ($validator->fails() && !$this->request->ajax()) {
            flash_msg('请填写正确的数据', 'warning');
        }

        $validator->validate();
    }

    public function validateRules()
    {
        $rules = [
            'app_name'                 => 'max:50',
            'official_account_app_id'  => 'max:255',
            'official_account_secret'  => 'max:255',
            'official_account_token'   => 'max:255',
            'official_account_aes_key' => 'max:255',
            'wechat_oauth_domain'      => 'max:255',
        ];

        return $rules;
    }

    public function validateMessages()
    {
        $messages = [
        ];

        return $messages;
    }

    public function validateAttributes()
    {
        $attributes = [
            'app_name'                 => '系统名',
            'official_account_app_id'  => '公众号 APP ID',
            'official_account_secret'  => '公众号 SECRET',
            'official_account_token'   => '公众号 TOKEN',
            'official_account_aes_key' => '公众号 AES KEY',
            'wechat_oauth_domain'      => '公众号授权域名',
        ];

        return $attributes;
    }

    private function getNeededUpdateConfigs()
    {
        $configs = [];
        $this->form->builder()->fields()->each(function (Field $field) use (&$configs) {
            $column = $field->column();
            $originalValue = config(static::$configPrefix.'.'.$column);

            if ($this->request->get($column) != $originalValue) {
                $configs[] = $column;
            }
        });

        return $configs;
    }

    private function updateConfigs($configs)
    {
        foreach ($configs as $configName) {
            ConfigModel::updateOrCreate(
                ['name' => $configName],
                ['value' => $this->request->get($configName)]
            );
        }

        return true;
    }

    public function upload()
    {
        return $this->form->handleFileUpload();
    }
}